MaterialUI使ってみる
概要
このページを参考に動かしてみる。
http://blog.takanabe.tokyo/2015/12/11/1778/
最終的には、左右のペーン、右ペーン内にリストで項目表示、みたいな画面が作りたい。
プロジェクトつくる
まずはnpm管理下のプロジェクトを作成。
mkdir mat
cd mat
npm init
package.jsonに次を記載
{
"name": "mat",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --hot --inline --progress --colors",
"build": "webpack --progress --colors"
},
"devDependencies": {
"babel-core": "^5.8.25",
"babel-eslint": "^4.1.3",
"babel-loader": "^5.3.2",
"babel-runtime": "^5.8.25",
"css-loader": "^0.19.0",
"eslint": "^1.6.0",
"eslint-loader": "^1.1.0",
"eslint-plugin-react": "^3.5.1",
"fbjs": "^0.2.1",
"file-loader": "^0.8.4",
"style-loader": "^0.12.4",
"webpack": "^1.12.2",
"webpack-dev-server": "^1.12.0",
"webpack-hot-middleware": "^2.2.0"
},
"dependencies": {
"classnames": "^2.1.2",
"fbjs": "^0.3.2",
"material-ui": "^0.13.0",
"react": "^0.14.0",
"react-addons-create-fragment": "^0.14.0",
"react-addons-pure-render-mixin": "^0.14.0",
"react-addons-transition-group": "^0.14.0",
"react-addons-update": "^0.14.0",
"react-dom": "^0.14.0",
"react-hot-loader": "^1.3.0",
"react-redux": "^3.1.0",
"react-tap-event-plugin": "^0.2.0",
"redux": "^3.0.2"
},
"author": "",
"license": "ISC"
}
で、
npm install
次に、webpack.config.jsを作成して、、いろいろ書きこむ。
module.exports = {
context: __dirname,
entry: {
jsx: "./src/index.jsx",
css: "./src/main.css",
html: "./src/index.html",
},
output: {
path: __dirname + "/static",
filename: "bundle.js",
},
module: {
preLoaders: [
//Eslint loader
{ test: /\.jsx?$/, exclude: /node_modules/, loader: "eslint-loader"},
],
loaders: [
{ test: /\.html$/, loader: "file?name=[name].[ext]" },
{ test: /\.css$/, loader: "file?name=[name].[ext]" },
{ test: /\.jsx?$/, exclude: /node_modules/, loaders: ["react-hot","babel-loader"]},
],
},
resolve: {
extensions: ['', '.js', '.jsx']
},
eslint: {
configFile: './.eslintrc'
},
};
eslintって何、ってなってるけどとりあえずやってみる。
touch .eslintrc
{
"env": {
"es6": true,
"browser": true,
"node": true
},
"rules": {
"curly": 0,
"comma-dangle": [2, "never"],
"comma-spacing": 0,
"eqeqeq": [2, "allow-null"],
"key-spacing": 0,
"no-underscore-dangle": 0,
"no-unused-expressions": 0,
"no-shadow": 0,
"no-shadow-restricted-names": 0,
"no-extend-native": 0,
"no-var": 2,
"new-cap": 0,
"quotes": 0,
"semi-spacing": 0,
"space-unary-ops": 0,
"space-infix-ops": 0,
"consistent-return": 0,
"strict": 0
},
"parser": "babel-eslint",
"plugins": [
"react"
],
"ecmaFeatures": {
"arrowFunctions": true,
"jsx": true
}
}
ああ、babel、、なるほど、、コンパイラの起動とかの設定なのか。概念としてはlint、っていう。
srcフォルダを作って、中にindex.htmlとか置く
mkdir src
touch ./src/index.html
touch ./src/index.jsx
touch ./src/main.css
で、npm run buildで、package.jsonで指定したbuildコマンドを実行。
npm run build
おお、、なんかコンパイルできたぞ、、
で、次に、index.jsxにいろいろ書いたりするんだけど、だいたいかいてあるまま進められる。
ただそのままだと動かなかったので、App.jsxだけ手を加えた。
import React, { Component, PropTypes } from "react";
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import Header from '../components/Header';
import MainSection from '../components/MainSection';
class App extends Component {
render() {
return (
<div>
<Header />
<MainSection />
</div>
);
}
}
export default App;
Material UIの作成は、componentsフォルダを作っていろいろファイル置いて、そこにReactComponentを記述しがてら行う。
mkdir components
touch ./components/Header.jsx
touch ./components/MainSection.jsx
Header.jsx
import React, { PropTypes, Component } from 'react';
import mui, {AppBar} from 'material-ui';
const ThemeManager = require('material-ui/lib/styles/theme-manager');
import MyRawTheme from '../src/material_ui_raw_theme_file'
class Header extends Component {
static get childContextTypes() {
return { muiTheme: React.PropTypes.object };
}
getChildContext(){
return { muiTheme: ThemeManager.getMuiTheme(MyRawTheme)};
}
render() {
return (
<header className="header">
<h1>AppBar Component</h1>
<AppBar title="React + Redux + Material UI Boilerplate" />
</header>
);
}
}
export default Header;
これでAppBarが出る。ほうほう。
細かい設定値はちょっと濃い行で、ファイルを使って指定している。
(面倒なのでオフってみた。)
次に、MainSection.jsx
import React, { Component, PropTypes } from 'react';
import mui, {CircularProgress,
Tabs,
Tab,
DatePicker
} from 'material-ui';
class MainSection extends Component {
render() {
return (
<div>
<h1>Progress Component</h1>
<CircularProgress mode="indeterminate" size={1.5} />
<CircularProgress mode="indeterminate" color={"red"} size={2} />
<br/>
<h1>Tab Component</h1>
<Tabs>
<Tab label="Tab One" value="0" />
<Tab label="Tab Two" value="1" />
<Tab label="Tab Three" value="2" />
</Tabs>
<br/>
<h1>DatePicker Component</h1>
<DatePicker hintText="Portrait Dialog" />
<br/>
</div>
);
}
}
export default MainSection;
で、ここまで書いたあと、npm start すると、ウォッチ状態になる + サーバ起動して、ブラウザで観れるようになる。
npm start
とりあえず2016/09/07現在でも動いてくれてよかった。
reduxって一体なにで、何してるんだろう、っていうのを後で追う。
MaterialUIでテーブルを表示してみる
http://www.material-ui.com/#/components/table から、
コードを見る(<>マークを押す) -> components フォルダにTableExampleSimple.jsxっていう名前でファイルを作る。
import React from 'react';
import {Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn} from 'material-ui';// 末尾を'material-ui'に変更してパスを合わせてる
const TableExampleSimple = () => (
<Table>
<TableHeader>
<TableRow>
<TableHeaderColumn>ID</TableHeaderColumn>
<TableHeaderColumn>Name</TableHeaderColumn>
<TableHeaderColumn>Status</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableRowColumn>1</TableRowColumn>
<TableRowColumn>John Smith</TableRowColumn>
<TableRowColumn>Employed</TableRowColumn>
</TableRow>
<TableRow>
<TableRowColumn>2</TableRowColumn>
<TableRowColumn>Randal White</TableRowColumn>
<TableRowColumn>Unemployed</TableRowColumn>
</TableRow>
<TableRow>
<TableRowColumn>3</TableRowColumn>
<TableRowColumn>Stephanie Sanders</TableRowColumn>
<TableRowColumn>Employed</TableRowColumn>
</TableRow>
<TableRow>
<TableRowColumn>4</TableRowColumn>
<TableRowColumn>Steve Brown</TableRowColumn>
<TableRowColumn>Employed</TableRowColumn>
</TableRow>
</TableBody>
</Table>
);
export default TableExampleSimple;
で、export句てのがあるのに初めて気づいた。ほう。
containersフォルダのApp.jsx側を以下のように変更
import React, { Component, PropTypes } from "react";
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import Header from '../components/Header';
import MainSection from '../components/MainSection';
import TableExampleSimple from '../components/TableExampleSimple'
class App extends Component {
// <Header />
// <MainSection />
render() {
return (
<div>
<TableExampleSimple />
</div>
);
}
}
export default App;
import句で、コンポーネントの要素 from ファイルパス みたいに指定できるんだな。なるほど。
で、App コンポーネントはUIの根っことして、index.jsxから参照されている。
import React from "react";
import ReactDOM from "react-dom";
import injectTapEventPlugin from "react-tap-event-plugin";
import App from '../containers/App';
//Needed for React Developer Tools
window.React = React;
//Needed for onTouchTap
//Can go away when react 1.0 release
//Check this repo:
//https://github.com/zilverline/react-tap-event-plugin
injectTapEventPlugin();
ReactDOM.render(
<App />,
document.getElementById("root")
);
色つきの部分での接続はこういう理屈になってたんだなーー把握。
表示はこんな風になった。
で、これあの、、手でJSXに書き直さないといけないの?
TableExampleSimple.jsx
import React from 'react';
import {Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn} from 'material-ui';
const TableExampleSimple = () => (
<Table>
<TableHeader>
<TableRow>
<TableHeaderColumn>ID</TableHeaderColumn>
<TableHeaderColumn>Name</TableHeaderColumn>
<TableHeaderColumn>Status</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableRowColumn>1</TableRowColumn>
<TableRowColumn>John Smith</TableRowColumn>
<TableRowColumn>Employed</TableRowColumn>
</TableRow>
<TableRow>
<TableRowColumn>2</TableRowColumn>
<TableRowColumn>Randal White</TableRowColumn>
<TableRowColumn>Unemployed</TableRowColumn>
</TableRow>
<TableRow>
<TableRowColumn>3</TableRowColumn>
<TableRowColumn>Stephanie Sanders</TableRowColumn>
<TableRowColumn>Employed</TableRowColumn>
</TableRow>
<TableRow>
<TableRowColumn>4</TableRowColumn>
<TableRowColumn>Steve Brown</TableRowColumn>
<TableRowColumn>Employed</TableRowColumn>
</TableRow>
</TableBody>
</Table>
);
export default TableExampleSimple;
UIの表示してるプロジェクトと、nodeのプロジェクトをどうマージするか
ぶっちゃけ通信周りとかはnodeのほうが取り回しが楽なんだけど、package.jsonにあるような要素の中から、webpackとreduxを省いても
無事にjsxからコードが生成できると思うのだがどうか、、まあ今回は無理かな。
exportの別の書き方
こんな風に書くこともできた。
import React, { Component, PropTypes } from "react";
import {TextField} from 'material-ui';
export default class TextFieldExampleSimple extends Component {
render() {
return (
<div>
<TextField
hintText="+-> lua codes for devices here."
multiLine={true}
rows={3}
rowsMax={10}
fullWidth={true}
/>
</div>
);
}
}
用途に応じてって感じかな。
reduxって何で何してんの
react-reduxとreduxがそれぞれ依存(package.json)にあって、
つづく。